﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.Filter;
using COFE.Core;

namespace COFE.Web
{
    public class CoreEntryList : EntryList, ISupportLinkTemplates
    {
        #region Constructor

        internal CoreEntryList(COFE.Core.IEntryList el, Guid rootId)
            : base(
            el is COFE.Core.IAutoEntryList ?
                EntryListType.Auto : EntryListType.Custom, el.Id, el.Name)
        {
            _el = el;
            _rootId = rootId;

            if (el is COFE.Core.IAutoEntryList)
            {
                var ael = el as COFE.Core.IAutoEntryList;

                Parameter = ael.GetFilterString();
            }
        }

        internal CoreEntryList(COFE.Core.IEntryList el)
            : this(el, Guid.Empty)
        {

        }

        #endregion

        #region Methods

        protected override Core.StatusType getStatus()
        {
            if (_el is COFE.Core.IAutoEntryList)
                return (_el as COFE.Core.IAutoEntryList).Status;
            else
                return Core.StatusType.Completed;
        }

        protected override IEnumerable<Entry> getEntries()
        {
            return from e in _el.Entries.ToArray() select Entry.FromCofeEntry(e);
        }

        public IEnumerable<LinkTemplate> GetLinkTemplates()
        {
            if (_el is IAutoEntryList)
            {
                IAutoEntryList ael = _el as IAutoEntryList;
                string searchFilter; int curPage; int itemPerPage; bool hasPrev; bool hasNext;
                checkAutoEntryList(out searchFilter, out curPage, out itemPerPage, out hasPrev, out hasNext);

                yield return new LinkTemplate(MediaType.EntryList,
                    RelationType.Self, ServiceConstants.Templates.Search);
                if (searchFilter != null)
                {
                    if (hasPrev)
                        yield return new LinkTemplate(MediaType.EntryList,
                        RelationType.Prev, ServiceConstants.Templates.PrevSearch);
                    if (hasNext)
                        yield return new LinkTemplate(MediaType.EntryList,
                        RelationType.Next, ServiceConstants.Templates.NextSearch);
                }
            }


            yield break;
        }

        private void checkAutoEntryList(out string searchFilter, out int curPage, out int itemPerPage,
            out bool hasPrev, out bool hasNext)
        {
            searchFilter = null; curPage = -1; itemPerPage = -1;
            hasPrev = false; hasNext = false;

            if (_el is IAutoEntryList)
            {
                IAutoEntryList ael = _el as IAutoEntryList;
                var pageFilter = ael.OptionFilters.FirstOrDefault(lf =>
                    lf is PaginateOptionFilter) as PaginateOptionFilter;

                var otherFilters = ael.EntryFilters.Concat<IFilter>(
                   ael.OptionFilters.Where(lf =>
                   !(lf is PaginateOptionFilter)));
                string otherFilterString = COFEShared.FilterParser.
                    FilterToFilterString(otherFilters);

                searchFilter = otherFilterString;

                if (pageFilter != null)
                {
                    itemPerPage = pageFilter.ItemsPerPage;
                    if (pageFilter.Page > 1)
                        hasPrev = true;
                    if (getEntries().Count() >= itemPerPage)
                        hasNext = true;

                    curPage = pageFilter.Page;

                   
                }
            }
        }

        public Dictionary<string, string> GetLinkParameterDic()
        {
            if (_el is IAutoEntryList)
            {
                IAutoEntryList ael = _el as IAutoEntryList;
                string searchFilter; int curPage; int itemPerPage; bool hasPrev; bool hasNext;
                checkAutoEntryList(out searchFilter, out curPage, out itemPerPage, out hasPrev, out hasNext);

                return new Dictionary<string, string>()
                {
                    { "#id#", _rootId.ToString() },
                    { "#ss#", searchFilter == null ? null : 
                        WSFilterUtils.GetFilterAsQuery(searchFilter) },                    
                    { "#curpage#", itemPerPage == -1 ? "" : String.Format("&page={0},{1}", (curPage), itemPerPage) },
                    { "#prevpage#", itemPerPage == -1 ? "" :String.Format("&page={0},{1}", (curPage - 1), itemPerPage) },
                    { "#nextpage#",itemPerPage == -1 ? "" :String.Format("&page={0},{1}", (curPage + 1), itemPerPage) }
                };
            }
            else
                return new Dictionary<string, string>()
                {
                };
        }

        public override IEnumerable<Link> GetLinks()
        {
            return this.CreateLinks();
        }

        #endregion

        #region Data

        COFE.Core.IEntryList _el;
        Guid _rootId;

        #endregion

        #region Public Properties

        #endregion


    }
}
